package com.abl.common.mybatis.strengthen;


import com.abl.common.util.ObjectKit;
import com.abl.common.util.coll.ArrayKit;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.enums.SqlLike;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;

import java.util.Arrays;
import java.util.Collection;

import static com.baomidou.mybatisplus.core.enums.SqlKeyword.LIKE;
import static com.baomidou.mybatisplus.core.enums.SqlKeyword.NOT_LIKE;

/**
 * 强化Wrapper
 */
public class Wrapper<T> extends UpdateWrapper<T> {

    /**
     * 查询字段
     */
    private final SharedString sqlSelect = new SharedString();

    public Wrapper<T> select(String... columns) {
        if (ArrayUtils.isNotEmpty(columns)) {
            this.sqlSelect.setStringValue(String.join(StringPool.COMMA, columns));
        }
        return this;
    }

    public String getSqlSelect() {
        return sqlSelect.getStringValue();
    }

    public Wrapper<T> findInSet(boolean condition, String column, Object val) {
        this.apply(condition, " FIND_IN_SET({0},`" + column + "`) ", val);
        return this;
    }

    public Wrapper<T> findInSet(String column, Object val) {
        return findInSet(true, column, val);
    }

    public Wrapper<T> eq(JSONObject jsonObject, String... columnKeys) {
        return eq(jsonObject, Arrays.asList(columnKeys));
    }

    public Wrapper<T> eq(JSONObject jsonObject, Collection<String> columnKeys) {
        columnKeys.forEach(columnKey -> {
            this.eq(columnKey, jsonObject.getString(columnKey));
        });
        return this;
    }

    public Wrapper<T> eqNotBlank(String column, Object val) {
        this.eq(ObjectKit.isNotBlank(val), column, val);
        return this;
    }

    public Wrapper<T> eqNotBlank(JSONObject jsonObject, String... columnKeys) {
        return eqNotBlank(jsonObject, Arrays.asList(columnKeys));
    }

    public Wrapper<T> eqNotBlank(JSONObject jsonObject, Collection<String> columnKeys) {
        columnKeys.forEach(columnKey -> {
            this.eqNotBlank(columnKey, jsonObject.getString(columnKey));
        });
        return this;
    }


    public Wrapper<T> inNotBlank(String column, Collection<?> coll) {
        this.in(ArrayKit.isNotBlank(coll), column, coll);
        return this;
    }

    public Wrapper<T> inNotBlank(String column, Object... values) {
        this.in(ArrayKit.isNotBlank(values), column, values);
        return this;
    }

    public Wrapper<T> notInNotBlank(String column, Collection<?> coll) {
        this.notIn(ArrayKit.isNotBlank(coll), column, coll);
        return this;
    }

    public Wrapper<T> notInNotBlank(String column, Object... values) {
        this.notIn(ArrayKit.isNotBlank(values), column, values);
        return this;
    }


    public Wrapper<T> likeNotBlank(String column, Object val) {
        this.likeNotBlank(LIKE, column, val, SqlLike.DEFAULT);
        return this;
    }

    public Wrapper<T> notLikeNotBlank(String column, Object val) {
        this.likeNotBlank(NOT_LIKE, column, val, SqlLike.DEFAULT);
        return this;
    }

    public Wrapper<T> likeLeftNotBlank(String column, Object val) {
        this.likeNotBlank(LIKE, column, val, SqlLike.LEFT);
        return this;
    }

    public Wrapper<T> likeRightNotBlank(String column, Object val) {
        this.likeNotBlank(LIKE, column, val, SqlLike.RIGHT);
        return this;
    }

    public Wrapper<T> likeNotBlank(JSONObject jsonObject, Collection<String> columnKeys) {
        this.likeNotBlank(LIKE, SqlLike.DEFAULT, jsonObject, columnKeys);
        return this;
    }

    public Wrapper<T> notLikeNotBlank(JSONObject jsonObject, Collection<String> columnKeys) {
        this.likeNotBlank(NOT_LIKE, SqlLike.DEFAULT, jsonObject, columnKeys);
        return this;
    }

    public Wrapper<T> likeLeftNotBlank(JSONObject jsonObject, Collection<String> columnKeys) {
        this.likeNotBlank(LIKE, SqlLike.LEFT, jsonObject, columnKeys);
        return this;
    }

    public Wrapper<T> likeRightNotBlank(JSONObject jsonObject, Collection<String> columnKeys) {
        this.likeNotBlank(LIKE, SqlLike.RIGHT, jsonObject, columnKeys);
        return this;
    }

    public Wrapper<T> likeNotBlank(JSONObject jsonObject, String... columnKeys) {
        this.likeNotBlank(LIKE, SqlLike.DEFAULT, jsonObject, Arrays.asList(columnKeys));
        return this;
    }

    public Wrapper<T> notLikeNotBlank(JSONObject jsonObject, String... columnKeys) {
        this.likeNotBlank(NOT_LIKE, SqlLike.DEFAULT, jsonObject, Arrays.asList(columnKeys));
        return this;
    }

    public Wrapper<T> likeLeftNotBlank(JSONObject jsonObject, String... columnKeys) {
        this.likeNotBlank(LIKE, SqlLike.LEFT, jsonObject, Arrays.asList(columnKeys));
        return this;
    }

    public Wrapper<T> likeRightNotBlank(JSONObject jsonObject, String... columnKeys) {
        this.likeNotBlank(LIKE, SqlLike.RIGHT, jsonObject, Arrays.asList(columnKeys));
        return this;
    }

    private Wrapper<T> likeNotBlank(SqlKeyword keyWord, SqlLike sqlLike, JSONObject jsonObject, Collection<String> columnKeys) {
        columnKeys.forEach(columnKey -> {
            this.likeNotBlank(keyWord, columnKey, jsonObject.getString(columnKey), sqlLike);
        });
        return this;
    }

    private Wrapper<T> likeNotBlank(SqlKeyword keyWord, String column, Object val, SqlLike sqlLike) {
        this.likeValue(ObjectKit.isNotBlank(val), keyWord, column, val, sqlLike);
        return this;
    }


}
